package mysql

import (
	"gorm.io/gorm/clause"

	"mxshop_srvs/goods_srv/model"
	proto "mxshop_srvs/goods_srv/proto/gen/v1"
	mql "mxshop_srvs/shared/mysql"
)

func (g *Gorm) GetCategoryCount() (int64, error) {
	return g.GetModelCount(&model.Category{})
}

func (g *Gorm) IsCategoryExists(id int32) (bool, error) {
	var count int64
	result := g.db.Model(&model.Category{}).Where(
		&model.Category{BaseModel: model.BaseModel{ID: id}},
	).Count(&count)
	if err := result.Error; err != nil {
		return false, err
	}
	if count != 1 {
		return false, nil
	}
	return true, nil
}

func (g *Gorm) CreateCategory(req *proto.CategoryInfoRequest) (int32, error) {
	var category = model.Category{
		BaseModel:        model.BaseModel{ID: mql.NewObjID, CreatedAt: mql.CreatedAt()},
		Name:             req.Name,
		Level:            req.Level,
		IsTab:            req.IsTab,
		ParentCategoryID: req.ParentCategory,
	}
	queryDB := g.db
	if req.Level == 1 {
		queryDB = queryDB.Omit("parent_category_id")
	}
	return category.ID, queryDB.Create(&category).Error
}

func (g *Gorm) CategoryList() ([]model.Category, error) {
	var categories []model.Category
	err := g.db.Where(&model.Category{Level: 1}).Preload("SubCategory.SubCategory").Find(&categories).Error
	return categories, err
}

func (g *Gorm) GetCategory(id int32) (model.Category, error) {
	var category model.Category
	return category, g.db.First(&category, id).Error
}

func (g *Gorm) GetSubCategories(id int32) ([]model.Category, error) {
	var subCategories []model.Category
	return subCategories, g.db.Where(model.Category{ParentCategoryID: id}).Find(&subCategories).Error
}

func (g *Gorm) UpdateCategory(category model.Category, req *proto.CategoryInfoRequest) (model.Category, int64, error) {
	categoryMap := make(map[string]interface{})
	if name := req.GetName(); name != "" {
		categoryMap["name"] = name
	}
	if parentCategory := req.GetParentCategory(); parentCategory != 0 {
		categoryMap["parent_category_id"] = parentCategory
	}
	if level := req.GetLevel(); level != 0 {
		categoryMap["level"] = level
	}
	categoryMap["is_tab"] = req.IsTab
	result := g.db.Model(&category).Clauses(clause.Returning{}).Updates(categoryMap)
	return category, result.RowsAffected, result.Error
}

func (g *Gorm) DeleteCategory(id int32) (int64, error) {
	result := g.db.Delete(&model.Category{}, id)
	return result.RowsAffected, result.Error
}
